package android.slc.box.core.widget.menu;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import javafx.collections.ObservableList;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;

import java.util.*;

public class MenuItemUtils {

    /**
     * 移除事件
     *
     * @param menuList
     */
    public static void removeActionByMenu(List<Menu> menuList) {
        removeActionByMenu(true, menuList);
    }

    /**
     * 移除事件
     *
     * @param menuList
     * @param containTree
     */
    public static void removeActionByMenu(boolean containTree, List<Menu> menuList) {
        if (CollectionUtil.isNotEmpty(menuList)) {
            removeActionByMenu(containTree, menuList.toArray(new Menu[0]));
        }
    }

    public static void removeActionByMenu(MenuItem... menuItems) {
        removeActionByMenu(true, menuItems);
    }

    /**
     * 移除事件
     *
     * @param menuItems
     * @param containTree
     */
    public static void removeActionByMenu(boolean containTree, MenuItem... menuItems) {
        if (menuItems != null) {
            for (MenuItem menuItem : menuItems) {
                if (menuItem.getOnAction() != null) {
                    menuItem.setOnAction(null);
                }
                if (containTree && menuItem instanceof Menu) {
                    Menu menu = (Menu) menuItem;
                    menu.getItems().forEach(MenuItemUtils::removeActionByMenu);
                }
            }
        }
    }


    public static void setItem(ObservableList<MenuItem> srcMenuItemList, String[] itemNames) {
        setItem(srcMenuItemList, ListUtil.toList(itemNames));
    }

    public static void setItem(ObservableList<MenuItem> srcMenuItemList, Collection<String> itemNames) {
        List<MenuItem> menuItemList = new ArrayList<>();
        CollectionUtil.forEach(itemNames, (value, index) -> {
            MenuItem menuItem = new MenuItem();
            menuItem.setText(value);
            menuItemList.add(menuItem);
        });
        setItem(srcMenuItemList, menuItemList);
    }

    public static void setItem(ObservableList<MenuItem> srcMenuItemList, List<MenuItem> menuItemList) {
        srcMenuItemList.clear();
        packingUserData(srcMenuItemList, menuItemList);
        srcMenuItemList.setAll(menuItemList);
    }

    public static void addItem(ObservableList<MenuItem> srcMenuItemList, MenuItem... menuItems) {
        addItem(srcMenuItemList, Arrays.asList(menuItems));
    }

    public static void addItem(ObservableList<MenuItem> srcMenuItemList, List<MenuItem> menuItemList) {
        packingUserData(srcMenuItemList, menuItemList);
        srcMenuItemList.addAll(menuItemList);
    }

    public static void packingUserData(ObservableList<MenuItem> srcMenuItemList, MenuItem... menuItems) {
        packingUserData(srcMenuItemList, Arrays.asList(menuItems));
    }

    public static void packingUserData(ObservableList<MenuItem> srcMenuItemList, List<MenuItem> menuItemList) {
        int srcSize = srcMenuItemList.size();
        CollectionUtil.forEach(menuItemList, (value, index) -> {
            Object userData = value.getUserData();
            MenuItemUserDataWarp menuItemUserDataWarp;
            if (userData instanceof MenuItemUserDataWarp) {
                menuItemUserDataWarp = (MenuItemUserDataWarp) userData;
            } else {
                menuItemUserDataWarp = new MenuItemUserDataWarp(userData);
            }
            menuItemUserDataWarp.setIndex(srcSize + index);
            value.setUserData(menuItemUserDataWarp);
        });
    }

    public static <T> T unpackingUserData(MenuItem menuItem) {
        Object userData = menuItem.getUserData();
        if (userData instanceof MenuItemUserDataWarp) {
            MenuItemUserDataWarp menuItemUserDataWarp = (MenuItemUserDataWarp) userData;
            userData = menuItemUserDataWarp.getUserData();
        }
        if (userData == null) {
            return null;
        }
        return (T) userData;
    }

    public interface OnItemClickListener {
        void onItemClick(MenuItem menuItem, Integer index);
    }

    public static class MenuItemUserDataWarp {
        private Object userData;
        private int index;

        public static MenuItemUserDataWarp createByIndex(int index) {
            return new MenuItemUserDataWarp(index);
        }

        public static MenuItemUserDataWarp createByUserData(Object userData) {
            return new MenuItemUserDataWarp(userData);
        }

        public static MenuItemUserDataWarp create(Object userData, int index) {
            return new MenuItemUserDataWarp(userData, index);
        }

        public MenuItemUserDataWarp(Object userData) {
            this.userData = userData;
        }

        public MenuItemUserDataWarp(int index) {
            this.index = index;
        }

        public MenuItemUserDataWarp(Object userData, int index) {
            this.userData = userData;
            this.index = index;
        }

        public Object getUserData() {
            return userData;
        }

        public void setUserData(Object userData) {
            this.userData = userData;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            MenuItemUserDataWarp that = (MenuItemUserDataWarp) o;
            return Objects.equals(userData, that.userData);
        }

        @Override
        public int hashCode() {
            return Objects.hash(userData);
        }
    }
}
